package polsense.filemerger;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;


import org.apache.commons.io.FileUtils;

/* Playing.java
 * Created on Oct 8, 2005
 * Copyright 2005 Pablo J. Lopez
 */

/**
 * @author Pablo J. Lopez
 */
public class Playing implements Runnable{

       
        private String[] fileExt;
        private File[] directoriesToScan;
        private File targetDirectory;
        private boolean deleteOriginalFiles;
        private boolean simulate;
    


	
	
	/* (non-Javadoc)
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		consolidate(fileExt,directoriesToScan,targetDirectory,deleteOriginalFiles,simulate);
		
	}



	/**
	 * @param delete 
	 * 
	 */
	public void consolidate(String[] extensions, File[] directoriesToScan,File targetDirectory, boolean delete,boolean simulate) {
		
		java.util.List errors = new LinkedList();
		Collection todosLosFiles = Collections.synchronizedCollection(new ArrayList());
		java.util.List waitingThreads = new ArrayList();
		// For Each location to be scanned we create a new FileScanner
		System.out.println("== Scanning MP3 Files ==");
		
		
		for (int i = 0; i < directoriesToScan.length; i++) {
			File file = directoriesToScan[i];
			FileScanner fileScanner = new FileScanner(file,todosLosFiles,extensions);
			fileScanner.run();
			
		}
		
		
		
		System.out.println("== GENERATING MP3 Index ==");
		MP3Index index = new MP3Index(todosLosFiles.size());
		for (Iterator iter = todosLosFiles.iterator(); iter.hasNext();) {
			CRCFile mp3 = (CRCFile) iter.next();
			index.addEntry(mp3.getFile(),mp3.getCrc());
			
		}
		if(errors.size() > 0){
		System.out.println("== "+errors.size() +" ERRORS FOUND =====");	
			for (Iterator iter = errors.iterator(); iter.hasNext();) {
				String element = (String) iter.next();
			
			}
		}
		System.out.println("Scanned: "+todosLosFiles.size());
		System.out.println("Duplicates: "+index.countMultipleInstances());
		
		Collection duplicates = index.getDuplicates();
		Collection nonDuplicates = index.getNonDuplicates();
				
		if(simulate)
                System.out.println("== Simulated Copying of MP3 Files to "+targetDirectory + " ==");
                else    System.out.println("== Copying MP3 Files to "+targetDirectory + " ==");
		copyFirstFromList(targetDirectory, duplicates,delete,simulate);
		copyFirstFromList(targetDirectory, nonDuplicates,delete,simulate);
                
                
                }
              

	/**
	 * @param targetDirectory
	 * @param duplicates
	 */
	private static void copyFirstFromList(File targetDirectory, Collection duplicates, boolean delete,boolean simulate) {
		for (Iterator iter = duplicates.iterator(); iter.hasNext();) {
			Collection element = (Collection) iter.next();
			boolean copied = false;
			
			for (Iterator iterator = element.iterator(); iterator.hasNext();) {
				String element2 = (String) iterator.next();
				if(!copied){
					copied = true;
					File src = new File(element2);
					try {
                                        
                                            System.out.println("\t COPYING - "+element2);
                                            
                                            if(!simulate)
                                            FileUtils.copyFile(src,new File(targetDirectory,src.getName()));
					
                                        } catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}else System.out.println("\t IGNORING - "+element2);
				
				if(delete && ! simulate)
					try {
						FileUtils.forceDelete(new File(element2));
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
			}
		}
	}
	


    public String[] getFileExt() {
        return fileExt;
    }

    public void setFileExt(String[] fileExt) {
        this.fileExt = fileExt;
    }

    public File[] getDirectoriesToScan() {
        return directoriesToScan;
    }

    public void setDirectoriesToScan(File[] directoriesToScan) {
        this.directoriesToScan = directoriesToScan;
    }

    public File getTargetDirectory() {
        return targetDirectory;
    }

    public void setTargetDirectory(File targetDirectory) {
        this.targetDirectory = targetDirectory;
    }

    public boolean isDeleteOriginalFiles() {
        return deleteOriginalFiles;
    }

    public void setDeleteOriginalFiles(boolean deleteOriginalFiles) {
        this.deleteOriginalFiles = deleteOriginalFiles;
    }

    public boolean isSimulate() {
        return simulate;
    }

    public void setSimulate(boolean simulate) {
        this.simulate = simulate;
    }

	/**
	 * @param ext
	 * @param scan
	 * @param directory
	 * @param files
	 * @param simulate
	 */
	public Playing(String[] ext, File[] scan, File directory, boolean files, boolean simulate) {
		super();
		// TODO Auto-generated constructor stub
		fileExt = ext;
		directoriesToScan = scan;
		targetDirectory = directory;
		deleteOriginalFiles = files;
		this.simulate = simulate;
	}
	
}
